#include "ClassFive.h"

Board::Board(int size) : size(size)
{
    board = new char *[size];
    for (int i = 0; i < size; i++)
    {
        board[i] = new char[size];
    }

    for (int i = 0; i < size; i++)
    {
        for (int j = 0; j < size; j++)
        {
            board[i][j] = '-';
        }
    }
}
Board::~Board()
{
    for (int i = 0; i < size; i++)
    {
        delete[] board[i];
    }
}
void Board::PrintBoard()
{
    printf("     ");
    for (int i = 0; i < size; i++)
    {
        printf(" %4d", i + 1);
    }
    printf("\n");
    for (int i = 0; i < size; i++)
    {
        printf("%4d ", i + 1);
        for (int j = 0; j < size; j++)
        {
            printf(" %4c", board[i][j]);
        }
        printf("\n");
    }
}

void Board::operator=(const Board &b)
{
    for (int i = 0; i < size; i++)
    {
        delete[] board[i];
    }
    board = new char *[b.size];

    for (int i = 0; i < b.size; i++)
    {
        for (int j = 0; j < b.size; j++)
        {
            board[i][j] = b.board[i][j];
        }
    }
}
Board::Board(const Board &b) {}
bool Board::IsValidPlace(int row, int column)
{
    if (row < 0 || row >= size || column < 0 || column >= size)
    {
        return false;
    }
    return true;
}

Player::Player(char player)
{
    this->player = player;
}

bool Player::Makemove(Board *b, int row, int column, char player)
{
    // 非法位置
    if (row < 0 || row > b->size - 1 || column > b->size - 1 || column < 0)
    {
        printf("非法的位置！请重新输入！\n");
        return false;
    }
    if (b->board[row][column] != '-')
    {
        printf("这个位置已经有棋子了，请重新输入！\n");
        return false;
    }
    b->board[row][column] = player;
    return true;
}

bool Player::CheckIsWin(Board *b, int row, int column, char player)
{
    int direction[4][2] =
        {
            {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
    // 遍历4个方向，数棋子数量
    for (int i = 0; i < 4; i++)
    {
        int count = 1;
        // 下一颗棋子位置
        int dx = row + direction[i][0];
        int dy = column + direction[i][1];
        while (b->IsValidPlace(dx, dy) && b->board[dx][dy] == player)
        {
            count++;
            if (count >= 5)
            {
                return true;
            }
            dx = dx + direction[i][0];
            dy = dy + direction[i][1];
        }
        dx = row - direction[i][0];
        dy = column - direction[i][1];
        while (b->IsValidPlace(dx, dy) == true && b->board[dx][dy] == player)
        {
            count++;
            if (count >= 5)
            {
                return true;
            }
            dx = dx - direction[i][0];
            dy = dy - direction[i][1];
        }
    }
    return false;
}

bool Player::CheckIsDraw(Board *b, Chess c)
{
    for (int i = 0; i < b->size; i++)
    {
        for (int j = 0; j < b->size; j++)
        {
            if (b->board[i][j] == c.chess)
            {
                return false;
            }
        }
    }
    return true;
}

bool AI::AIMakeMove(Board *b, char player, char ai, int playerRow, int playerColumn, Player p)
{
    // 优先取胜
    for (int i = 0; i < b->size; i++)
    {
        for (int j = 0; j < b->size; j++)
        {
            if (b->board[i][j] == '-')
            {
                b->board[i][j] = ai;
                if (p.CheckIsWin(b, i, j, ai) == true)
                {
                    return true;
                }
                b->board[i][j] = '-';
            }
        }
    }
    // 阻止2步
    int count = 0;
    for (int i = 0; i < b->size; i++)
    {
        for (int j = 0; j < b->size; j++)
        {
            if (b->board[i][j] == '-')
            {
                b->board[i][j] = player;
                if (MayWin(b, i, j, player) == true)
                {
                    count++;
                    if (count == 2)
                    {
                        b->board[i][j] = ai;
                        return true;
                    }
                }
                b->board[i][j] = '-';
            }
        }
    }
    // 阻止一步获胜
    for (int i = 0; i < b->size; i++)
    {
        for (int j = 0; j < b->size; j++)
        {
            if (b->board[i][j] == '-')
            {
                b->board[i][j] = player;
                if (p.CheckIsWin(b, i, j, player) == true)
                {
                    b->board[i][j] = ai;
                    return true;
                }
                b->board[i][j] = '-';
            }
        }
    }
    // 随机下在玩家周围
    int direction[8][2] =
        {
            {1, 0}, {-1, 0}, {0, -1}, {0, 1}, {1, 1}, {-1, 1}, {1, -1}, {-1, -1}

        };
    // 随机数产生跟随机种子
    // 随机种子不变，随机数不变
    // 以当前世界作为随机种子
    while (1)
    {
        srand(time(NULL));
        int i = rand() % 8;
        int dx = playerRow + direction[i][0];
        int dy = playerColumn + direction[i][1];
        if (b->IsValidPlace(dx, dy) && b->board[dx][dy] == '-')
        {
            b->board[dx][dy] = ai;

            return true;
        }
    }
}

bool AI::MayWin(Board *b, int row, int column, char player)
{
    int direction[4][2] =
        {
            {1, 0}, {1, 1}, {0, 1}, {-1, 1}};
    // 遍历4个方向，数棋子数量
    for (int i = 0; i < 4; i++)
    {
        int count = 1;
        // 下一颗棋子位置
        int dx = row + direction[i][0];
        int dy = column + direction[i][1];
        while (b->IsValidPlace(dx, dy) && b->board[dx][dy] == player)
        {
            count++;
            if (count >= 4)
            {
                return true;
            }
            dx = dx + direction[i][0];
            dy = dy + direction[i][1];
        }
        dx = row - direction[i][0];
        dy = column - direction[i][1];
        while (b->IsValidPlace(dx, dy) == true && b->board[dx][dy] == player)
        {
            count++;
            if (count >= 4)
            {
                return true;
            }
            dx = dx - direction[i][0];
            dy = dy - direction[i][1];
        }
    }
    return false;
}